package com.buybuyyi.stylistcrm.security.services.impl;

import com.buybuyyi.stylistcrm.security.mapper.SecurityUserMapper;
import com.buybuyyi.stylistcrm.security.mapper.SecurityUserRoleMapper;
import com.buybuyyi.stylistcrm.security.po.SecurityUser;
import com.buybuyyi.stylistcrm.security.po.SecurityUserRoleKey;
import com.buybuyyi.stylistcrm.security.rest.DefaultAccessTokenAuthenticationToken;
import com.buybuyyi.stylistcrm.security.rest.DefaultUserDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import stylistcrm.core.services.order.exception.BizException;
import stylistcrm.core.services.security.dto.OperationAuthorityDto;
import stylistcrm.core.services.security.dto.UserDto;
import stylistcrm.core.services.security.dto.ViewAuthorityDto;
import stylistcrm.core.services.security.exception.ReloginException;
import stylistcrm.core.services.security.exception.UserNameAlreadyExistsException;
import stylistcrm.core.services.security.service.SecurityService;
import stylistcrm.core.services.user.User;

import java.util.Date;
import java.util.List;

/**
 * Created by yanwc on 2016/9/8.
 */
@Service
public class SecurityServiceImpl implements SecurityService {

    @Autowired
    SecurityUserMapper securityUserMapper;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    SecurityUserRoleMapper securityUserRoleMapper;

    @Override
    public UserDto getCurrentUser() throws ReloginException {
        Object userDetails = SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();
        if(userDetails != null&&userDetails instanceof DefaultUserDetails){
            return ((DefaultUserDetails)userDetails).getUserDto();
        }else{
            return null;
        }
    }

    @Override
    public UserDto getUserById(long id) {
        UserDto userDto = new UserDto();
       SecurityUser user =  securityUserMapper.selectByPrimaryKey(id);
        userDto.setLock(user.getIsLock());
        userDto.setEnable( user.getIsEnable());
        userDto.setLoginName(user.getLoginName());
        userDto.setUserName(user.getUserName());
        userDto.setId(user.getId());
        return userDto;
    }

    @Override
    public boolean isOperationAuthority(String viewName, String operationName) throws ReloginException {
        //获取缓存用户信息，查询当前用户是否具有操作权限
        DefaultUserDetails userDetails = (DefaultUserDetails) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();
        if(userDetails != null) {
            List<OperationAuthorityDto> list =  userDetails.getUserDto().getListOperationAuthority();
            if(list != null){
                for(OperationAuthorityDto d:list){
                    if(d.getViewName().equals(viewName) && d.getCode().equals(operationName)){
                        return true;
                    }
                }
            }
        }
        return false;
    }

    @Override
    public UserDto singup(String name, String loginName, String password) throws UserNameAlreadyExistsException {
        //需要加密密码
        UserDto userDto = new UserDto();
        SecurityUser user = new SecurityUser();
        user.setCreateTime(new Date());
        user.setUserName(name);
        user.setLoginName(loginName);
        user.setPassword(bCryptPasswordEncoder.encode(password));
        user.setIsEnable(true);
        user.setIsLock(false);
        int rev = securityUserMapper.insert(user);
        //直接登录系统
        if(rev>0){
            DefaultAccessTokenAuthenticationToken token
                    = new DefaultAccessTokenAuthenticationToken(user.getLoginName(),password);
            //TODO 添加token自动登录
            Authentication authentication =  authenticationManager.authenticate(token);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            userDto.setToken(token.toString());
            userDto.setPassword(user.getPassword());
            userDto.setListViewAuthority(null);
            userDto.setListOperationAuthority(null);
            userDto.setNavigation(null);
            userDto.setEnable(user.getIsEnable());
            userDto.setLock(user.getIsLock());
            userDto.setListDataAuthority(null);
            userDto.setUserName(user.getUserName());
            userDto.setLoginName(user.getLoginName());
            userDto.setId(user.getId());
            return userDto;
        }else{
            return null;
        }
    }

    @Override
    public boolean isViewAuthority(String viewName) throws ReloginException {
        DefaultUserDetails userDetails = (DefaultUserDetails) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();
        if(userDetails != null) {
            List<ViewAuthorityDto> list =  userDetails.getUserDto().getListViewAuthority();
            if(list != null){
                for(ViewAuthorityDto d:list){
                    if(d.getName().equals(viewName)){
                        return true;
                    }
                }
            }
        }
        return false;
    }

    @Override
    public boolean disable(UserDto userDto) {
        return false;
    }

    @Override
    public boolean enable(UserDto userDto) {
        return false;
    }

    /**
     * 保存用户角色关联关系表
     * @param secUserId
     * @param roleId
     * @return
     * @throws BizException
     */
    @Override
    public Boolean saveUserRole(Long secUserId, Long roleId) throws BizException {
        SecurityUserRoleKey userRoleKey=new SecurityUserRoleKey();
        userRoleKey.setSecUserId(secUserId);
        userRoleKey.setSecRoleId(roleId);
        Integer ret=securityUserRoleMapper.insertSelective(userRoleKey);
        if(ret>0){
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }
}
